package krillr.Util;
import robocode.*;
import java.util.*;

public class Tracker {
    public Rectangle2d fieldRectangle;
    public ArrayList locationHistory = new ArrayList();
    public ArrayList bullets = new ArrayList();
    public ArrayList predictors = new ArrayList();
    public KrillBot bot;
    
    public String name = "";
    public Vector2d vector = new Vector2d();
    public double energy = 0;
    public double oldEnergy = 0;
    public double updateTime = 0;
    public double dangerFactor = 0;
        
    public void run() {
        if(hasFired()) {
            oldEnergy = energy;
            double be = bulletEnergy();
            Point2d bulletLocation = lastKnownLocation();
            double enemyHeading = heading();
            double bulletHeading = KrillUtil.getBearing(bulletLocation, new Point2d(bot.getX(), bot.getY())) + enemyHeading;
            BulletTracker bullet = new BulletTracker(bulletLocation, bulletHeading, be, bot.getTime());
            bullets.add(bullet);
        }
        
        checkBullets();
    }
    
    public void setDangerFactor(double df) {
        dangerFactor = df;
    }
    
    public double dangerFactor() {
        return dangerFactor;
    }
    
    public void checkBullets() {
        Iterator it = new ArrayList(bullets).iterator();
        while(it.hasNext()) {
            BulletTracker bullet = (BulletTracker)it.next();
            Point2d bP = bullet.currentLocation(bot.getTime());
            if(!fieldRectangle.containsBullet(bullet, bot.getTime()))
                bullets.remove(bullet);
        }
    }
    
    public Point2d lastKnownLocation() {
        return (Point2d)locationHistory.get(locationHistory.size()-1);
    }
    
    public Point2d guessLocation() {
        Predictor predictor = (Predictor)predictors.get(predictors.size()-1);
        Vector2d newVector = predictor.getVector();
        if((velocity() == 0) | (lastKnownDistance() <= 12))
            return lastKnownLocation().applyVector(vector.Multiply(bot.getTime()-updateTime));
        else
            return lastKnownLocation().applyVector(newVector);
    }
    
    public Point2d myLocation() { return new Point2d(0,0); }
    public double myHeading() { return 0.0; }
    
    public double lastKnownBearing() {
        return KrillUtil.getBearing(myLocation(), lastKnownLocation());
    }
    
    public double guessBearing() {
        return KrillUtil.getBearing(myLocation(), guessLocation());
    }
    
    public double lastKnownAbsoluteBearing() {
        return KrillUtil.getBearing(myLocation(), lastKnownLocation()) + myHeading();
    }
    
    public double guessAbsoluteBearing() {
        return KrillUtil.getBearing(myLocation(), guessLocation()) + bot.getHeadingRadians();
    }
    
    public double lastKnownDistance() {
        return KrillUtil.getDistance(myLocation(), lastKnownLocation());
    }
    
    public double guessDistance() {
        return KrillUtil.getDistance(myLocation(), guessLocation());
    }
    
    public boolean hasFired() {
        double delta = oldEnergy - energy;
        return ((1 <= delta) & (delta <= 3));
    }
    
    public double bulletEnergy() {
        if(hasFired())
            return energy - oldEnergy;
        else
            return 0;
    }
    
    public ArrayList bullets() { return bullets; }
    
    public void setVector(Vector2d v) { vector = v; }
    public void setEnergy(double e) {
        if(oldEnergy == 0)
            oldEnergy = e;
        else
            oldEnergy = energy;
        energy = e;
    }
    public void setHeading(double h) { vector.setDirection(h); }
    public void setVelocity(double v) { vector.setMagnitude(v); }
    public void setLocation(Point2d p) { locationHistory.add(p); }
    public Vector2d vector() { return vector; }
    public double energy() { return energy; }
    public double previousEnergy() { return oldEnergy; }
    public double heading() { return vector.getDirection(); }
    public double velocity() { return vector.getMagnitude(); }
    public String name() { return name; }
}